using System;
using System.IO;
using Oracle.ManagedDataAccess.Client;

namespace OracleInternal.BinXml
{
	internal class BinXmlArrayStream : IDisposable
	{
		protected BinaryReader m_BinReader;

		protected bool m_bInit;

		protected bool m_ReadOnlyStream;

		protected bool m_Disposed;

		internal long Position
		{
			get
			{
				return m_BinReader.BaseStream.Position;
			}
			set
			{
				m_BinReader.BaseStream.Position = value;
			}
		}

		public void Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}

		internal BinXmlArrayStream()
		{
		}

		internal BinXmlArrayStream(byte[] buffer, long size)
		{
			m_BinReader = new BinaryReader(new MemoryStream(buffer));
			m_ReadOnlyStream = true;
			m_bInit = true;
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!m_Disposed)
			{
				if (disposing && m_BinReader != null)
				{
					m_BinReader.Dispose();
					m_BinReader = null;
				}
				m_Disposed = true;
			}
		}

		internal virtual void Init()
		{
			if (m_ReadOnlyStream)
			{
				m_bInit = true;
			}
		}

		internal void Reset()
		{
			Dispose();
			m_bInit = false;
			Init();
		}

		internal byte[] ReadBytes(int count, int startPos = -1)
		{
			long position = Position;
			if (startPos != -1)
			{
				m_BinReader.BaseStream.Position = startPos;
			}
			byte[] result = m_BinReader.ReadBytes(count);
			if (startPos != -1)
			{
				Position = position;
			}
			return result;
		}

		internal void ReadAndCopyBytes(byte[] destination, long offset, long count)
		{
			if (destination == null)
			{
				throw new OracleException(ResourceStringConstants.XML_TYPE_BINARY_INTERNAL_ERROR, string.Empty, string.Empty, ObxmlDecodeResponse.GetErrorMessage(ObxmlErrorTypes.BufferInsufficient));
			}
			byte[] array = ReadBytes((int)count, (int)offset);
			for (int i = 0; i < count; i++)
			{
				destination[i] = array[i];
			}
		}

		internal byte ReadByte()
		{
			return m_BinReader.ReadByte();
		}

		internal byte[] ReadAllBytes(long startPos = -1L)
		{
			if (m_ReadOnlyStream)
			{
				long num = m_BinReader.BaseStream.Length;
				if (startPos != -1)
				{
					num -= startPos;
					m_BinReader.BaseStream.Position = startPos;
				}
				if (num > 0)
				{
					return m_BinReader.ReadBytes((int)num);
				}
			}
			return null;
		}
	}
}
